/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = rtp_comm.h                                         */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/20 by songbb                               */
/*******************************************************************/

#ifndef __RTP_COMM_H_
#define __RTP_COMM_H_

#include <sys/time.h>

#include "frlog.h"

#include "rtp_core.h"

#define APM_RTP_DBG 0
#define APM_RTP_ENABLE_FRLOG 0

#define APM_TCPRTP_HDR_PKTLEN 4
#define APM_TCPRTP_HDR_MAGIC 0x24
#define APM_TCPRTP_NONSTANDARD_HDR_PKTLEN 2

#define APM_RTP_DETECT_MAX 3

#define APM_RTP_HDR_LEN 12

/* 标识符变量的初始化值 */
#define APM_RTP_FLAG_UNSET -1

/* Version is the first 2 bits of the first octet*/
#define APM_RTP_VERSION(octet) ((octet) >> 6)

/* Padding is the third bit; no need to shift, because true is any value
   other than 0! */
#define APM_RTP_PADDING(octet) ((octet) & 0x20)

/* Extension bit is the fourth bit */
#define APM_RTP_EXTENSION(octet)    ((octet) & 0x10)

/* CSRC count is the last four bits */
#define APM_RTP_CSRC_COUNT(octet)   ((octet) & 0xF)

/* Marker is the first bit of the second octet */
#define APM_RTP_MARKER(octet)   ((octet) & 0x80)

/* Payload type is the last 7 bits */
#define APM_RTP_PAYLOAD_TYPE(octet) ((octet) & 0x7F)

#define APM_SIP_INVITE_BEGIN_TIME "INVITE_BEGIN_TIME"
#define APM_SIP_INVITE_PLAY_URI "INVITE_PLAY_URI"

#define APM_RTP_REPORT_MODULE_NAME "rtp"
#define APM_RTP_REPORT_RESP_PACKETS_LOST APM_REPORT_KEY_RESP"."APM_RTP_REPORT_MODULE_NAME".packets_lost"

#define APM_RTP_STREAMTYPE2STR(x) ((x==APM_RTP_STREAM_TYPE_UNKNOWN)?"UNKNOWN": \
                                 ((x==APM_RTP_STREAM_TYPE_RTP)?"RTP": \
                                 ((x==APM_RTP_STREAM_TYPE_TCPRTP)?"TCP/RTP": \
                                 ((x==APM_RTP_STREAM_TYPE_TCPRTP_NONSTANDARD)?"TCP/RTP.NONSTANDARD":"UNKNOWN"))))

#define KRED        "\x1B[0;31m"
#define KSALMON     "\x1B[1;31m"
#define KGREEN      "\x1B[0;32m"
#define KLIMEGREEN  "\x1B[1;32m"
#define KYELLOW     "\x1B[0;33m"
#define KORANGE     "\x1B[0;34m"
#define KBLUE       "\x1B[1;34m"
#define KMAGENTA    "\x1B[0;35m"
#define KPINK       "\x1B[1;35m"
#define KCYAN       "\x1B[0;36m"
#define RESET       "\x1B[0m"

#if APM_RTP_DBG
    #define RTP_PRINT(...) printf(__VA_ARGS__)
    #define RTP_PRINT_DETAIL(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(__VA_ARGS__))
    #define RTP_PRINT_DBG(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KGREEN),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_FATAL(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KORANGE),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_EMERG(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KRED),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_ALERT(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KSALMON),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_CRIT(...) (printf("[%s, Line:%u, %s()]",\
                            __FILE__,__LINE__,__func__),\
                            printf(KMAGENTA),\
                            printf(" "__VA_ARGS__),\
                            printf(RESET))
    #define RTP_PRINT_ERR(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KPINK),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_WARN(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KYELLOW),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_NOTICE(...) (printf("[%s, Line:%u, %s()]",\
                        __FILE__,__LINE__,__func__),\
                        printf(KLIMEGREEN),\
                        printf(" "__VA_ARGS__),\
                        printf(RESET))
    #define RTP_PRINT_INFO(...) (printf("[%s, Line:%u, %s()]",\
                            __FILE__,__LINE__,__func__),\
                            printf(KBLUE),\
                            printf(" "__VA_ARGS__),\
                            printf(RESET))
     #define PRINT_HEX_STRING(a,b,c) (printf("[%s, Line:%u, %s()] ",\
                            __FILE__,__LINE__,__func__),\
                            printf(KCYAN),\
                            printf(a":["),rtp_print_hex_string(b,c),printf("]\n"),\
                            printf(RESET))
    #define RTP_PRINT_PACKET_SPECIFIED(tag, packet, offset, len) (printf("[%s, Line:%u, %s()] ",\
                            __FILE__,__LINE__,__func__),\
                            printf(KORANGE),\
                            printf(tag":["),rtp_print_packet_specified(packet,offset,len),printf("]\n"),\
                            printf(RESET))

    #define RTP_PRINT_PACKET_CURRENT(a,b) (printf("[%s, Line:%u, %s()] ",\
                            __FILE__,__LINE__,__func__),\
                            printf(KCYAN),\
                            printf(a":["),rtp_print_packet_current(b),printf("]\n"),\
                            printf(RESET))

    #define RTP_PRINT_PACKET(a,b) (printf("[%s, Line:%u, %s()] ",\
                            __FILE__,__LINE__,__func__),\
                            printf(KCYAN),\
                            printf(a":["),rtp_print_packet(b),printf("]\n"),\
                            printf(RESET))
    #define RTP_PRINT_TIMEVAL(a,b) (printf("[%s, Line:%u, %s()]",\
                            __FILE__,__LINE__,__func__),\
                            printf(KGREEN),\
                            printf(" %s", a), \
                             rtp_print_timeval(b),\
                             printf(RESET))
#else
    #define RTP_PRINT(...)
    #define RTP_PRINT_DETAIL(...)
    #define RTP_PRINT_DBG(...)
    #define RTP_PRINT_FATAL(...)
    #define RTP_PRINT_EMERG(...)
    #define RTP_PRINT_ALERT(...)
    #define RTP_PRINT_CRIT(...)
    #define RTP_PRINT_ERR(...)
    #define RTP_PRINT_WARN(...)
    #define RTP_PRINT_NOTICE(...)
    #define RTP_PRINT_INFO(...)
    #define PRINT_HEX_STRING(a,b,c)
    #define RTP_PRINT_PACKET_SPECIFIED(tag, packet, offset, len)
    #define RTP_PRINT_PACKET_CURRENT(a,b)
    #define RTP_PRINT_PACKET(a,b)
    #define RTP_PRINT_TIMEVAL(a,b)
#endif

#if APM_RTP_ENABLE_FRLOG
    #define RTP_FRLOG_ERROR(...) FRLOG_ERROR_DETAIL(...)
#else
#define RTP_FRLOG_ERROR(...)
#endif

#define RTP_MALLOCK_ERR RTP_PRINT_EMERG("can not malloc memory\n"); \
                          FRLOG_ERROR_DETAIL("can not malloc memory");

void rtp_free(void **pp_buffer);

unsigned long rtp_get_timestamp(struct timeval *p_st_timestamp);

void rtp_print_timeval(struct timeval st_timestamp);

void rtp_bin_to_hex_string(char *p_inbuff
                            , int i_len
                            , char *p_outbuff);

void rtp_print_hex_string(char *p_buff
                        , int i_len);

void rtp_report(Conntrack *p_st_conn
                , Frhash_header *p_st_hash_report
                , unsigned long ul_fbt
                , unsigned long ul_bytes
                , unsigned long ul_ffft
                , unsigned long ul_pluff
                , int *p_i_analyze_ret);

void rtp_report_resp_only(Conntrack *p_st_conn
                        , Frhash_header *p_st_hash_report
                        , unsigned long ul_fbt
                        , unsigned long ul_bytes
                        , unsigned long ul_ffft
                        , unsigned long ul_pluff
                        , int *p_i_analyze_ret);

void rtp_init_detect_sess(Rtp_detect_session **pp_st_detect_sess);

#endif
